﻿using Microsoft.Identity.Client;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MSALPost
{
    public class MSGraphHelper
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="_ClientId">已注册应用程序的 应用程序（客户端）ID</param>
        /// <param name="_Tenant">租户 ID 或 租户名称</param>
        public MSGraphHelper(string _ClientId, string _Tenant)
        {
            TokenCacheHelper.Build(_ClientId, _Tenant,true);
        }

        //Set the scope for API call to user.read
        string[] scopes = new string[] { "user.read" };

        public async Task<Result> CallGraph(string url)
        {
            Microsoft.Identity.Client.AuthenticationResult authResult = null;
            var app = TokenCacheHelper.PublicClientApp;
            Result ret = new Result();


            IAccount firstAccount;

            var accounts = await app.GetAccountsAsync();
            firstAccount = accounts.FirstOrDefault(); 
            if(firstAccount==null)
            {
                ret.Error = $"Account not found";
                ret.Code = 0;
                return ret;
            }

            try
            {
                authResult = await app.AcquireTokenSilent(scopes, firstAccount)
                    .ExecuteAsync();
            }
            catch (MsalUiRequiredException ex)
            {
                // A MsalUiRequiredException happened on AcquireTokenSilent. 
                // This indicates you need to call AcquireTokenInteractive to acquire a token
                //System.Diagnostics.Debug.WriteLine($"MsalUiRequiredException: {ex.Message}");
                ret.Error = $"MsalUiRequiredException: {ex.Message}";
                ret.Code = 0;

                try
                {
                    authResult = await app.AcquireTokenInteractive(scopes)
                        .WithAccount(firstAccount) 
                        .WithPrompt(Prompt.SelectAccount)
                        .ExecuteAsync();
                }
                catch (MsalException msalex)
                {
                    ret.Error = $"Error Acquiring Token:{System.Environment.NewLine}{msalex}";
                    ret.Code = 0;
                }
            }
            catch (Exception ex)
            {
                ret.Error = $"Error Acquiring Token Silently:{System.Environment.NewLine}{ex}";
                ret.Code = 0;
            }

            if (authResult != null)
            {
                ret.Code = 1;
                ret.Data = await GetHttpContentWithToken(url, authResult.AccessToken);
                ret.Auth = authResult; 
            }
            return ret;
        }


        /// <summary>
        /// Perform an HTTP GET request to a URL using an HTTP Authorization header
        /// </summary>
        /// <param name="url">The URL</param>
        /// <param name="token">The token</param>
        /// <returns>String containing the results of the GET operation</returns>
        public async Task<string> GetHttpContentWithToken(string url, string token)
        {
            var httpClient = new System.Net.Http.HttpClient();
            System.Net.Http.HttpResponseMessage response;
            try
            {
                var request = new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Get, url);
                //Add the token in Authorization header
                request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
                response = await httpClient.SendAsync(request);
                var content = await response.Content.ReadAsStringAsync();
                return content;
            }
            catch (Exception ex)
            {
                return ex.ToString();
            }
        }
    }
}
